<template>
  <div>
    <!-- 内容区域 -->
    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <span>职位列表</span>
      </div>
      <!-- 搜索区域 -->
      <div class="search-box">
        <el-form :inline="true" :model="q">
          <el-form-item label="职位分类">
            <el-select v-model="q.cate_id" placeholder="请选择分类" size="small">
              <el-option v-for="obj in artCateList" :key="obj.id" :label="obj.name" :value="obj.id"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="发布状态" style="margin-left: 15px">
            <el-select v-model="q.state" placeholder="请选择状态" size="small">
              <el-option label="已发布" value="已发布"></el-option>
              <el-option label="草稿" value="草稿"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" size="small" @click="choseFn">筛选</el-button>
            <el-button type="info" size="small" @click="resetFn">重置</el-button>
          </el-form-item>
        </el-form>
        <!-- 发表文章的按钮 -->
        <el-button type="primary" size="small" class="btn-pub" @click="pubArt">发布职位</el-button>
      </div>

      <!-- 文章表格区域 -->
      <el-table :data="artList" style="width: 100%" border stripe>
        <el-table-column label="职位标题" prop="title">
          <template v-slot="scope">
            <el-link type="primary" @click="details(scope.row.id)">{{
              scope.row.title
            }}</el-link>
          </template>
        </el-table-column>
        <el-table-column label="分类" prop="name"></el-table-column>
        <!-- <el-table-column label="是否删除" prop="is_delete"></el-table-column> -->
        <el-table-column label="发表时间" prop="pub_date">
          <!-- 作用域插槽 -->
          <template v-slot="scope">
            <span>{{ $formatDate(scope.row.pub_date) }}</span>
          </template>
        </el-table-column>
        <el-table-column label="状态" prop="state"></el-table-column>
        <el-table-column label="操作">
          <template v-slot="scope">
            <el-button type="danger" size="mini" @click="deleteArt(scope.row.id)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页区域 -->
      <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
        :current-page.sync="q.pagenum" :page-sizes="[2, 3, , 5, 10]" :page-size.sync="q.pagesize"
        layout="total,sizes, prev, pager, next" :total="total">
      </el-pagination>
    </el-card>
    <!-- dialog发布职位区域 -->
    <el-dialog title="发表职位" :visible.sync="pubDialogVisible" fullscreen :before-close="handleClose"
      @close="dialogClose">
      <!-- 发布职位的对话框 -->
      <el-form :model="pubForm" :rules="pubFormRules" ref="pubFormRef" label-width="100px">
        <el-form-item label="职位标题" prop="title">
          <el-input v-model="pubForm.title" placeholder="请输入标题"></el-input>
        </el-form-item>
        <el-form-item label="职位工资" prop="salary">
          <el-input v-model="pubForm.salary" placeholder="请输入职位薪资"></el-input>
        </el-form-item>
        <el-form-item label="工作公司" prop="company">
          <el-input v-model="pubForm.company" placeholder="请输入公司名称"></el-input>
        </el-form-item>
        <el-form-item label="工作地址" prop="address">
          <el-input v-model="pubForm.address" placeholder="请输入工作地址"></el-input>
        </el-form-item>
        <el-form-item label="工作经验" prop="experience">
          <!-- <el-input v-model="pubForm.experience" placeholder="请输入工作经验"></el-input> -->
          <el-select v-model="pubForm.experience" placeholder="请选择">
            <el-option v-for="item in experience" :key="item.value" :value="item.value">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="学历要求" prop="grade">
          <!-- <el-input v-model="pubForm.experience" placeholder="请输入工作经验"></el-input> -->
          <el-select v-model="pubForm.grade" placeholder="请选择">
            <el-option v-for="item in grade" :key="item.value" :value="item.value">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="职位分类" prop="cate_id">
          <el-select v-model="pubForm.cate_id" placeholder="请选择分类" style="width: 100%">
            <el-option v-for="obj in artCateList" :key="obj.id" :label="obj.name" :value="obj.id"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="职位内容" prop="content">
          <quill-editor @blur="chageFN" v-model="pubForm.content"></quill-editor>
        </el-form-item>
        <el-form-item label="职位封面" prop="cover_img">
          <!-- 用来显示封面的图片 -->
          <!-- src="../../assets/images/cover.jpg" -->
          <img src="../../assets/images/cover.jpg" alt="" class="cover-img" ref="imgRef" @click="imgclick" />
          <br />
          <!-- 文件选择框，默认被隐藏 -->
          <input type="file" style="display: none" accept="image/*" ref="iptFileRef" @change="changeCover" />
          <!-- 选择封面的按钮 -->
          <el-button type="text" @click="selectCover">+ 选择封面</el-button>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="pubArticle('已发布')">发布</el-button>
          <el-button type="info" @click="pubArticle('草稿')">存为草稿</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
    <!-- 职位详情 -->
    <el-dialog :visible.sync="dialogVisible" width="60%">
      <el-card class="detailscard">
        <el-row :gutter="20">
          <el-col :xs="12" :lg="19" :sm="15">
            <div class="header_txt">
              <h1 class="title">{{ detail.title }}</h1>
              <div class="articleInfo">
                <span>类别：{{ detail.cate_name }}</span>
                <span>发布人：{{ detail.nickname || detail.username }}</span>
                <span>发布于：{{ $formatDate(detail.pub_date) }}</span>
              </div>
            </div>
          </el-col>
          <el-col :xs="6" :lg="4" :sm="4">
            <div class="header_img">
              <img v-if="detail.cover_img" :src="baseURL + detail.cover_img" alt="" srcset="">
            </div>
          </el-col>
        </el-row>

        <el-divider></el-divider>
        <div class="content">
          <span v-html="detail.content"></span>
        </div>
      </el-card>
    </el-dialog>
  </div>
</template>

<script>
  import {
    getArtCateAPI,
    pubArticleAPI,
    getArticleAPI,
    articleDetailsAPI,
    deleteArtAPI
  } from '@/api/index'
  // 标签和样式中，引入图片文件可以写路径，在JS里引入图片要用import引入
  // webpack会把图片变为一个base64字符串/在打包后的图片临时地址
  // JS里引入图片，就用import引入,让webpack把它当做模板数据，是转换成打包后的图片路径还是base64字符串
  import imgObj from '../../assets/images/cover.jpg'
  import {
    baseURL
  } from '@/utils/request'
  export default {
    name: 'ArtList',
    data() {
      return {
        // 学历要求
        grade: [{
          value: '学历不限'
        }, {
          value: '大专'
        }, {
          value: '本科'
        }, {
          value: '硕士'
        }],
        // 工作经验选择项
        experience: [{
          value: '在校/应届'
        }, {
          value: '1年以下'
        }, {
          value: '1-3年'
        }, {
          value: '3-5年'
        }, {
          value: '5年以上'
        }],
        baseURL,
        // 查询参数对象
        q: {
          pagenum: 1, // 默认获取第一页的数据
          pagesize: 2, // 默认一页获取两条
          cate_id: '',
          state: ''
        },
        imgObj,
        pubDialogVisible: false, // 发布文章dialog的开关
        dialogVisible: false, // 文章详情dialog的开关
        pubForm: {
          // 发布文章的表单的数据对象
          title: '',
          cate_id: '',
          content: '',
          cover_img: null, // 封面图片，保存的是一个文件
          state: '', // 以下为新增
          salary: '',
          address: '',
          experience: '',
          grade: '',
          company: ''
        },
        pubFormRules: {
          // 发布文章的表单的验证规则对象
          title: [{
              required: true,
              message: '请输入职位标题',
              trigger: 'blur'
            },
            {
              min: 1,
              max: 30,
              message: '职位标题的长度为1-30个字符',
              trigger: 'blur'
            }
          ],
          cate_id: [{
            required: true,
            message: '请选择职位分类',
            trigger: 'change'
          }],
          content: [
            // content对应quill-editor富文本编辑器，它不是el提供表单标签
            // el-input等输入框在blur失焦事件时进行校验
            // 下拉菜单，单选框，复选框，是在change事件时进行校验
            // quill-editor2个事件都没有，所以输入内容也不会自动走校验
            // 解决：自己给quill-editor绑定change事件（在文档里查到的它支持change事件内容改变事件）
            {
              required: true,
              message: '请输入职位内容',
              trigger: 'change'
            }
          ],
          cover_img: [{
            required: true,
            message: '请选择封面',
            trigger: 'change'
          }],
          salary: [{
            required: true,
            message: '请输入薪资',
            trigger: 'blur'
          }],
          address: [{
            required: true,
            message: '请输入工作地址',
            trigger: 'blur'
          }],
          experience: [{
            required: true,
            message: '请选择工作经验',
            trigger: 'blur'
          }],
          grade: [{
            required: true,
            message: '请选择学历要求',
            trigger: 'blur'
          }],
          company: [{
            required: true,
            message: '请输入公司名称',
            trigger: 'blur'
          }]
        },
        artCateList: [], // 保存文章分类列表
        artList: [], // 保存文章列表
        total: 0, // 保存现有文章的总数
        url: '', // 保存选择的封面图片文件
        detail: [] // 保存请求的文章详情数据
      }
    },
    methods: {
      // 知识点回顾
      // 1.await只能用在被async修饰的函数内
      // async修饰：就是在当前函数名左边加async关键字，如果没有函数名，那就在形参的左边加async
      // 原因：async修饰的函数就是异步函数，如果此函数被调用，总是返回一个全新Promise
      // 而且本次函数调用因为是异步函数，所以外面的同步代码继续执行，而await暂停代码只能暂停async函数内的，等待await后面异步结果
      // 2.await只能捕获到成功的结果
      // 获取文章分类
      async getArtCateList() {
        const {
          data: res
        } = await getArtCateAPI()
        if (res.status !== 0) return this.$message.error(res.message)
        console.log('获取的文章分类', res)
        this.artCateList = res.data
        // console.log('文章分类数据', res)
      },
      // 获取文章列表
      async getArticleFN() {
        const {
          data: res
        } = await getArticleAPI(this.q)
        console.log('获取文章列表', res)
        this.total = res.total
        this.artList = res.data
      },
      // 发布文章的对话框关闭之前
      async handleClose(done) {
        // done 调用就会关闭对话框
        const cconfirmresult = await this.$confirm(
          '此操作会使未保存内容丢失, 是否继续?',
          '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }
        ).catch((err) => err)
        // 点击取消
        if (cconfirmresult === 'cancel') return
        // 确认关闭
        done()
      },
      // 发布文章按钮的点击事件  让对话框出现
      pubArt() {
        this.pubDialogVisible = true
      },
      // 选择封面按钮的方法->让文件选择窗口出现
      selectCover() {
        this.$refs.iptFileRef.click()
      },
      // 点击img标签->也可以让让文件选择窗口出现
      imgclick() {
        this.$refs.iptFileRef.click()
      },
      // 用户选择了封面文件
      // event原生事件对象
      changeCover(event) {
        const files = event.target.files
        if (files.length === 0) {
          this.pubForm.cover_img = null
          // img要显示回默认cover.png
          this.$refs.imgRef.setAttribute('src', imgObj)
        } else {
          this.pubForm.cover_img = files[0]
          // 把文件转成一个临时地址
          const url = URL.createObjectURL(files[0])
          this.$refs.imgRef.setAttribute('src', url)
        }
        // 这个校验应该在用户选择完图片后执行
        this.$refs.pubFormRef.validateField('cover_img')
      },
      // 发布文章，调用后台接口，存到数据库里
      // Body 参数(multipart/form-data) 表单对象
      pubArticle(state) {
        this.$refs.pubFormRef.validate(async (valid) => {
          if (valid) {
            this.pubForm.state = state
            const fd = new FormData() // 准备一个表单数据对象的容器 FormData类是HTML5新出的专门为了装文件内容和其他参数的一个容器
            // fd.append('参数名',值)
            fd.append('title', this.pubForm.title)
            fd.append('cate_id', this.pubForm.cate_id)
            fd.append('content', this.pubForm.content)
            fd.append('cover_img', this.pubForm.cover_img)
            fd.append('state', this.pubForm.state)
            // 新增
            fd.append('salary', this.pubForm.salary)
            fd.append('address', this.pubForm.address)
            fd.append('experience', this.pubForm.experience)
            fd.append('grade', this.pubForm.grade)
            fd.append('company', this.pubForm.company)
            console.log(fd)
            const {
              data: res
            } = await pubArticleAPI(fd)
            console.log('新增文章', res)
            if (res.status !== 0) return this.$message.error(res.message)
            this.$message.success(res.message)
            // 关闭对话框
            this.pubDialogVisible = false
            // 再次请求文章列表数据
            this.getArticleFN()
          } else {
            return false
          }
        })
      },
      // 手动给富文本编辑器绑定的change事件，当富文本编辑器里的内容改变时走此方法
      chageFN() {
        this.$refs.pubFormRef.validateField('content')
      },
      // dialog关闭之前，把添加文章的form表单清空
      dialogClose() {
        this.$refs.pubFormRef.resetFields()
        // 我们需要手动给封面标签img重新设置一个值，因为它没有受到v-model影响
        this.$refs.imgRef.setAttribute('src', imgObj)
      },
      // 分页 每页条数改变触发
      handleSizeChange(sizes) {
        this.q.pagesize = sizes
        this.q.pagenum = 1
        this.getArticleFN()
      },
      // 当前页码改变时触发
      handleCurrentChange(nowpage) {
        this.q.pagenum = nowpage
        this.getArticleFN()
      },
      // 筛选按钮的点击事件
      choseFn() {
        // 目的：当有了筛选的条件，让页码回归1，每页的条数回归2
        this.q.pagenum = 1
        this.q.pagesize = 2
        this.getArticleFN()
      },
      // 重置按钮的点击事件
      resetFn() {
        this.q.pagenum = 1
        this.q.pagesize = 2
        this.q.cate_id = ''
        this.q.state = '' // 对象改变，v-model关联的表单标签也会变为空

        this.getArticleFN()
      },
      // 点击文章标题查看文章详情
      //
      //
      ///
      //
      async details(id) {
        this.dialogVisible = true
        console.log('ID是', id)
        const {
          data: res
        } = await articleDetailsAPI(id)
        console.log('文章详情', res.data)
        this.detail = res.data
        // console.log('文章详情', this.detail)
      },
      // 删除文章按钮的点击事件
      async deleteArt(id) {
        const {
          data: res
        } = await deleteArtAPI(id)
        if (res.status !== 0) return this.$message.error(res.message)
        this.$message.success(res.message)
        console.log('删除文章', res)
        // 再次获取文章列表
        this.resetFn() // 激活重置按钮的点击事件
      }
    },
    mounted() {
      // 请求分类数据
      this.getArtCateList()
      // 请求文章列表
      this.getArticleFN()
    }
  }
</script>

<style lang="less" scoped>
  // scoped作用：让style里的选择器，只能选中当前组件的标签(为了保证样式的独立性，不影响别的组件)
  // scoped原理：(多加了一个data-v的属性选择器)
  // webpack打包的时候，会给组件标签上添加data-v-hash值，然后也会给所有选择器后面
  // 加上一个[data-v-hash]值的属性选择器
  // <标签 data-v-390246 class="my_a"></标签>
  // 选择器会变成 my_a[data-v-390246]
  // 重要注意事项：scoped只会给当前组件所有原生标签添加data-v-hash值属性，还会给组件标签内根标签添加data-v-hasn值属性
  // 组件内的标签不会添加
  .search-box {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;

    .btn-pub {
      margin-top: 5px;
    }
  }

  .el-pagination {
    width: 100%;
    margin: 10px auto;
    align-items: center;
  }

  .box-card {
    span {
      font-size: 15px;
    }
  }

  // 设置图片封面的宽高
  .cover-img {
    width: 400px;
    height: 280px;
    object-fit: contain;
    cursor: pointer;
  }

  // 设置富文本编辑器的默认最小高度
  // ::v-deep作用: 穿透选择, 正常style上加了scope的话, 会给.ql-editor[data-v-hash]属性, 只能选择当前页面标签或者组件的根标签
  // 如果想要选择组件内的标签(那些标签没有data-v-hash值)所以正常选择选不中, 加了::v-deep空格前置的话, 选择器就会变成如下形式
  // [data-v-hash] .ql-editor 这样就能选中组件内的标签的class类名了
  // Vue提供了一个::v-deep样式语法，设置后，可以把属性选择器自动添加到左侧 [data-v-hash值] .ql-editor
  ::v-deep .ql-editor {
    min-height: 300px;
  }

  .detailscard {
    width: 100%;
    min-height: 500px;

    .title {
      font-size: 20px;
    }

    .articleInfo {
      display: flex;
      justify-content: flex-start;

      :nth-child(n + 2) {
        margin-left: 10px;
      }
    }

    .header_img {
      img {
        max-height: 150px;
        object-fit: contain;
        margin-right: 5px;
      }
    }

    .content :nth-child(n) {
      max-width: 100%;
    }
  }
</style>
